/**
 * 使用fetch API封装的请求工具
 */
import { ElNotification, ElMessageBox, ElMessage, ElLoading } from 'element-plus';
import { getToken } from '@/utils/auth';

const env = import.meta.env;
// 优先使用环境变量，其次使用默认值
const baseURL = env.VITE_API_BASE_URL || 'http://36.213.76.124:6060';

// 默认配置
const defaultOptions = {
    timeout: 60000 * 3 // 默认超时时间 60s *3
};

// 合并配置
const mergeOptions = (config = {}) => {
    return {
        ...defaultOptions,
        ...config,
        headers: {
            'Authorization': `Bearer ${getToken() || ''}`,
            'Content-Type': 'application/json',
            ...config.headers
        }
    };
};

// 创建请求选项
const createFetchOptions = (config) => {
    const { method = '', data, headers, signal } = config;
    const fetchOptions = {
        method,
        headers,
        signal
    };

    const methodLower = method.toLowerCase();
    if (methodLower !== 'get' && methodLower !== 'head' && data !== null) {
        fetchOptions.body = JSON.stringify(data);
    }

    return fetchOptions;
};

// 错误处理
const handleFetchError = (error, config) => {
    const { onError } = config;

    let errorMessage = '请求失败';
    let errorType = 'network';

    if (error.name === 'AbortError') {
        errorMessage = '请求已取消';
        errorType = 'aborted';
    } else if (error.message.includes('超时')) {
        errorMessage = error.message;
        errorType = 'timeout';
    } else {
        errorMessage = error.message || errorMessage;
    }

    const enhancedError = {
        ...error,
        message: errorMessage,
        type: errorType,
        url: baseURL + config.url,
        method: config.method
    };

    onError?.(enhancedError);
    return Promise.reject(enhancedError);
};

// 响应处理
const handleResponse = async (response, config) => {
    if (!response.ok) {
        throw new Error(`HTTP错误! 状态码: ${response.status}, 状态文本: ${response.statusText}`);
    }

    const contentType = response.headers.get('content-type');
    if (contentType && contentType.includes('application/json')) {
        return response.json();
    }
    return response.text();
};

// 使用fetch API发送请求，非流式请求
// 构建带查询参数的URL
const buildUrlWithParams = (url, params) => {
    if (!params || typeof params !== 'object') return url;
    
    const queryParams = new URLSearchParams();
    Object.entries(params).forEach(([key, value]) => {
        if (value !== undefined && value !== null) {
            queryParams.append(key, value);
        }
    });
    
    const queryString = queryParams.toString();
    return queryString ? `${url}${url.includes('?') ? '&' : '?'}${queryString}` : url;
};

// 然后在fetchRequest函数中使用
export const fetchRequest = (config = {}) => {
    const options = mergeOptions(config);
    const controller = new AbortController();
    const signal = controller.signal;
    
    // 处理GET请求的查询参数
    let url = options.url;
    const methodLower = options.method.toLowerCase();
    if ((methodLower === 'get' || methodLower === 'head') && options.data) {
        url = buildUrlWithParams(url, options.data);
    }

    // 创建超时处理
    let timeoutId;
    const timeoutPromise = new Promise((_, reject) => {
        timeoutId = setTimeout(() => {
            controller.abort();
            reject(new Error('请求超时'));
        }, options.timeout);
    });

    const fetchOptions = createFetchOptions({ ...options, signal });

    const requestPromise = fetch(baseURL + url, fetchOptions)
        .then(response => {
            clearTimeout(timeoutId);
            return handleResponse(response, options);
        })
        .catch(error => handleFetchError(error, options));

    return Promise.race([requestPromise, timeoutPromise]);
};

export default fetchRequest;

/**
 * 使用fetch API请求，支持流式响应处理
 * @param {Object} config - 配置对象
 * @returns {Object} 包含promise和abort方法的对象
 */
export const fetchStreamRequest = (config = {}) => {
    const options = mergeOptions(config);
    const {
        onProgress,        // 数据块回调
        onComplete,        // 流式传输完成回调
        chunkSeparator = '\n' // 数据块分隔符
    } = options;

    // 创建AbortController用于中止请求
    const controller = new AbortController();
    const signal = controller.signal;

    // 标记请求是否被用户主动中止
    let isUserAborted = false;

    // 创建超时处理
    let timeoutId;
    const timeoutPromise = new Promise((_, reject) => {
        timeoutId = setTimeout(() => {
            controller.abort();
            reject(new Error('请求超时'));
        }, options.timeout);
    });

    // 发送请求
    const requestPromise = new Promise((resolve, reject) => {
        fetch(baseURL + options.url, createFetchOptions({ ...options, signal }))
            .then(response => {
                clearTimeout(timeoutId);

                if (!response.ok) {
                    throw new Error(`HTTP错误! 状态码: ${response.status}`);
                }

                // 处理流式响应
                const reader = response.body.getReader();
                const decoder = new TextDecoder('utf-8');
                let buffer = '';

                function readStream() {
                    reader.read().then(({ done, value }) => {
                        if (done) {
                            // 处理剩余缓冲区
                            if (buffer && onProgress) {
                                onProgress(buffer);
                            }
                            onComplete?.();
                            resolve(buffer); // 解析完成，返回完整响应
                            return;
                        }

                        // 解码新数据并添加到缓冲区
                        const chunk = decoder.decode(value, { stream: true });
                        buffer += chunk;

                        // 按分隔符分割数据块
                        const chunks = buffer.split(chunkSeparator);
                        buffer = chunks.pop() || ''; // 保留未完成部分

                        // 处理完整的数据块
                        chunks.forEach(dataChunk => {
                            if (onProgress) {
                                onProgress(dataChunk);
                            }
                        });
                        // 继续读取流
                        readStream();
                    }).catch(error => {
                        clearTimeout(timeoutId);
                        // 区分用户主动中止和其他错误
                        if (isUserAborted) {
                            return;
                        }
                        reject(error);
                    });
                }

                // 开始读取流
                readStream();
            })
            .catch(error => {
                clearTimeout(timeoutId);
                if (isUserAborted) {
                    return;
                }
                handleFetchError(error, options);
            });
    });

    const promise = Promise.race([requestPromise, timeoutPromise]);

    return {
        promise,
        abort: () => {
            clearTimeout(timeoutId);
            isUserAborted = true;
            try {
                controller.abort();
            } catch (error) {
                console.warn('中止请求时发生错误:', error);
            }
        }
    };
};

/**
 * 简化的文件下载函数
 * @param {Object} config - 配置对象
 * @returns {Promise} 下载Promise
 */
export const fetchDownload = (config = {}) => {
    const options = mergeOptions({
        ...config,
        fileName: config.fileName || 'download.docx'
    });
    const controller = new AbortController();
    const signal = controller.signal;

    // 创建超时处理
    let timeoutId;
    const timeoutPromise = new Promise((_, reject) => {
        timeoutId = setTimeout(() => {
            controller.abort();
            reject(new Error('请求超时'));
        }, options.timeout);
    });

    const fetchOptions = createFetchOptions({ ...options, signal });

    const requestPromise = fetch(baseURL + options.url, fetchOptions)
        .then(response => {
            clearTimeout(timeoutId);

            if (!response.ok) {
                throw new Error('文件不存在或服务器错误');
            }
            return response.blob();
        })
        .then(blob => {
            // 尝试从响应头获取文件名
            let fileName = options.fileName;
            const contentDisposition = fetchOptions.headers['content-disposition'];
            if (contentDisposition) {
                const match = contentDisposition.match(/filename="?([^"\s]+)"?/);
                if (match && match[1]) {
                    fileName = match[1];
                }
            }

            // 创建临时下载链接
            const url = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = fileName;
            document.body.appendChild(a);
            a.click();
            // 清理
            setTimeout(() => {
                window.URL.revokeObjectURL(url);
                document.body.removeChild(a);
            }, 100);
            return blob;
        })
        .catch(error => handleFetchError(error, options));

    return Promise.race([requestPromise, timeoutPromise]);
};

